home *** CD-ROM | disk | FTP | other *** search
- /* callfunc - call shared library function in a shell script
- *
- * Copyright (C) 1995 by Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation. This software is provided "as is" without express or
- * implied warranty.
- *
- * V1.0: 12/Jan/95 first version
- */
- #define THIS_PROGRAM "callfunc"
- #define THIS_VERSION "1.0"
-
- static const char amiga_version[] = "\0$VER: " THIS_PROGRAM " " THIS_VERSION " (" __COMMODORE_DATE__ ")";
-
- #include <exec/types.h>
- #include <exec/libraries.h>
- #include <dos/dos.h>
- #include <dos/rdargs.h>
- #include <stdlib.h>
- #include <string.h>
-
- #define SysBase_DECLARED
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/utility.h>
-
- extern struct Library *SysBase;
-
- extern __stkargs LONG CallFunction(struct Library *base, LONG offset,
- LONG d0, LONG d1, LONG d2, LONG d3, LONG d4,
- LONG d5, LONG d6, LONG d7,
- APTR a0, APTR a1, APTR a2, APTR a3, APTR a4);
-
-
- const char Template[] =
- "OFFSET/N,FROM/K,D0/K,D1/K,D2/K,D3/K,D4/K,D5/K,D6/K,D7/K,A0/K,A1/K,A2/K,A3/K,A4/K,VOID/S,OPEN/K,CLOSE/K,VER=VERSION/K/N";
-
- __aligned struct {
- LONG * offset;
- STRPTR libbase;
- STRPTR D0, D1, D2, D3, D4, D5, D6, D7;
- STRPTR A0, A1, A2, A3, A4;
- LONG noresult; /* 'void' */
- STRPTR open;
- STRPTR close;
- LONG * libversion;
- } Args;
-
-
-
- static APTR mkaddr(STRPTR str);
-
- void
- _main()
- {
- struct RDArgs *rdargs;
- LONG rc = RETURN_OK;
-
- struct Library *cfbase;
- char *dummy;
- LONG result;
-
- char buf[16] = {0};
- /* RawDoFmt() 'put' function
- * MC68000 machine code:
- * move.b d0,(a3)+
- * rts
- * Idea by Doug Walker, walker@unx.sas.com
- */
- __aligned const unsigned char rawdocode[] = { 0x16, 0xC0, 0x4E, 0x75 };
-
-
- if( SysBase->lib_Version < 37 ) {
- #define MESSAGE "requires AmigaOS 2.04 or higher\n"
- Write(Output(), MESSAGE, sizeof(MESSAGE)-1);
- _exit(RETURN_FAIL);
- #undef MESSAGE
- }
-
- if( rdargs = ReadArgs(Template, (LONG *)&Args, NULL) ) {
- LONG libversion = 0;
- if( Args.libversion )
- libversion = *(Args.libversion);
-
- if( Args.open ) {
- cfbase = OpenLibrary(Args.open, libversion);
- RawDoFmt("%ld\n", (APTR)&cfbase, (void (*)())rawdocode, buf);
- PutStr(buf);
- if( !cfbase )
- rc = RETURN_WARN;
- }
- else
- if( Args.close ) {
- cfbase = (struct Library *)strtoul(Args.close, &dummy, 0);
- if( cfbase )
- CloseLibrary(cfbase);
- else {
- PutStr("invalid library base\n");
- rc = RETURN_WARN;
- }
- }
- else {
- BOOL closelib = FALSE;
-
- cfbase = (struct Library *)strtoul(Args.libbase, &dummy, 0);
- if( !cfbase || *dummy ) {
- cfbase = OpenLibrary(Args.libbase, libversion);
- closelib = TRUE;
- }
-
- if( !cfbase ) {
- PutStr("invalid library name or base\n");
- rc = RETURN_ERROR;
- cfbase = NULL;
- }
- else {
- LONG d0 = 0, d1 = 0, d2 = 0, d3 = 0, d4 = 0, d5 = 0, d6 = 0, d7 = 0;
- APTR a0 = 0, a1 = 0, a2 = 0, a3 = 0, a4 = 0;
- LONG offset = 0;
-
- if( Args.offset )
- offset = *(Args.offset);
- if( offset > 0 )
- offset = -offset;
- if( (offset % 6) || (offset > -30) ) {
- PutStr("invalid library offset\n");
- rc = RETURN_ERROR;
- }
- else {
- d0 = (LONG)mkaddr(Args.D0);
- d1 = (LONG)mkaddr(Args.D1);
- d2 = (LONG)mkaddr(Args.D2);
- d3 = (LONG)mkaddr(Args.D3);
- d4 = (LONG)mkaddr(Args.D4);
- d5 = (LONG)mkaddr(Args.D5);
- d6 = (LONG)mkaddr(Args.D6);
- d7 = (LONG)mkaddr(Args.D7);
- a0 = mkaddr(Args.A0);
- a1 = mkaddr(Args.A1);
- a2 = mkaddr(Args.A2);
- a3 = mkaddr(Args.A3);
- a4 = mkaddr(Args.A4);
-
- result = CallFunction(cfbase, offset, d0, d1, d2, d3, d4, d5, d6, d7,
- a0, a1, a2, a3, a4);
- if( !Args.noresult ) {
- RawDoFmt("%ld\n", (APTR)&result, (void (*)())rawdocode, buf);
- PutStr(buf);
- }
- }
- if( closelib )
- CloseLibrary(cfbase);
- }
- }
- FreeArgs(rdargs);
- }
- else {
- PutStr("required argument missing\n");
- rc = RETURN_ERROR;
- }
- _exit((int)rc);
- }
-
-
-
- static APTR
- mkaddr(STRPTR str)
- {
- APTR adr = NULL;
-
- if( str ) {
- if( str[0] == '@' )
- adr = (APTR)(str+1);
- else {
- char *dummy;
- adr = (APTR)strtoul(str, &dummy, 0);
- }
- }
- return adr;
- }
-
-